/*** Created Time: 2022年5月16日 20:59:44 ***/
/*** Author: Eric                        ***/

#ifndef _MY_INTERRUPT_H_
#define _MY_INTERRUPT_H_

#include <onix/types.h>

#define     IDT_SIZE        256  // 中断描述符表的大小

// 外中断向量号定义，要加上0x20
#define     IRQ_CLOCK       0    // 时钟
#define     IRQ_KEYBOARD    1    // 键盘
#define     IRQ_CASCADE     2    // 8259 从片控制器
#define     IRQ_SERIAL_2    3    // 串口 2
#define     IRQ_SERIAL_1    4    // 串口 1
#define     IRQ_PARALLEL_2  5    // 并口 2
#define     IRQ_FLOPPY      6    // 软盘控制器
#define     IRQ_PARALLEL_1  7    // 并口 1
#define     IRQ_RTC         8    // 实时时钟
#define     IRQ_REDIRECT    9    // 重定向 IRQ2
#define     IRQ_MOUSE       12   // 鼠标
#define     IRQ_MATH        13   // 协处理器 x87
#define     IRQ_HARDDISK    14   // ATA 硬盘第一通道
#define     IRQ_HARDDISK2   15   // ATA 硬盘第二通道

#define     IRQ_MASTER_NR   0x20 // 8253主片起始向量号
#define     IRQ_SLAVE_NR    0x28 // 8253从片起始向量号

// 中断描述符定义
typedef struct gate_t
{
    u16 offset0;    // 段内偏移 0 ~ 15 位
    u16 selector;   // 代码段选择子
    u8 reserved;    // 保留不用
    u8 type : 4;    // 任务门/中断门/陷阱门
    u8 segment : 1; // segment = 0 表示系统段
    u8 DPL : 2;     // 使用 int 指令访问的最低权限
    u8 present : 1; // 是否有效
    u16 offset1;    // 段内偏移 16 ~ 31 位
} _packed gate_t;   // 不优化对齐

typedef void *handler_t;        // 中断处理函数

// 中断初始化函数
void interrupt_init(void);
// 通知中断控制器，中断处理结束
void send_eoi(int vector);

// 设置中断处理函数
void set_interrupt_handler(u32 irq, handler_t handler);
// 设置中断屏蔽字函数
void set_interrupt_mask(u32 irq, bool enable);

bool interrupt_disable(void);             // 清除 IF 位，返回设置之前的值
bool get_interrupt_state(void);           // 获得 IF 位
void set_interrupt_state(bool state);     // 设置 IF 位

#endif